package com.yhsoft.buyer.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yhsoft.buyer.controller.request.UserDeleteInVo;
import com.yhsoft.buyer.controller.request.UserQueryInVo;
import com.yhsoft.buyer.controller.request.UserUpdateInVo;
import com.yhsoft.buyer.controller.response.BuyerUserOutVo;
import com.yhsoft.buyer.controller.response.WxLoginOutVo;
import com.yhsoft.buyer.entity.BuyerUser;
import com.yhsoft.buyer.mapper.BuyerUserMapper;
import com.yhsoft.buyer.service.IBuyerUserService;
import com.yhsoft.common.exception.BusinessException;
import com.yhsoft.common.response.PageResult;
import com.yhsoft.common.service.TokenService;
import com.yhsoft.common.utils.AccessTokenUtil;
import com.yhsoft.common.utils.IDGenerator;
import com.yhsoft.common.utils.JwtUtil;
import com.yhsoft.sys.entity.BaicInterfaceConfig;
import com.yhsoft.sys.entity.User;
import com.yhsoft.sys.service.IBaicInterfaceConfigService;
import com.yhsoft.wxprogram.controller.request.GetPhoneNumInVo;
import com.yhsoft.wxprogram.controller.request.UserInfoInVo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 买家 服务实现类
 * </p>
 *
 * @author yyyyyyyh
 * @since 2023-09-26
 */
@Service
public class BuyerUserServiceImpl extends ServiceImpl<BuyerUserMapper, BuyerUser> implements IBuyerUserService {

    private static final Logger logger = LoggerFactory.getLogger(BuyerUserServiceImpl.class);


    @Resource
    private JwtUtil jwtUtil;

    @Resource
    private IBaicInterfaceConfigService iBaicInterfaceConfigService;

    private static final String loginUrl = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code";

    private static final String getAccessTokenUrl = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s";

    private static final String getPhoneNumberUrl = "https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=%s";

    @Override
    public WxLoginOutVo loginByWx(String appId, String code, boolean test) {
        String sessionKey;
        String openId;

        LambdaQueryWrapper<BaicInterfaceConfig> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BaicInterfaceConfig::getAppId, appId);
        BaicInterfaceConfig baicInterfaceConfig = iBaicInterfaceConfigService.getBaseMapper().selectOne(queryWrapper);
        if (baicInterfaceConfig == null) {
            throw new BusinessException("登录出错，请稍后重试～");
        }

        if (test) {
            sessionKey = "sessionKey";
            openId = "openId";
        } else {
            String secret = baicInterfaceConfig.getAppSecret();
            //String requestUrl = String.format(loginUrl, WeChatSecretConstant.APP_ID, WeChatSecretConstant.SECRET, code);
            String requestUrl = String.format(loginUrl, appId, secret, code);
            logger.info("loginUrl:" + requestUrl);
            RestTemplate restTemplate = new RestTemplate();
            ResponseEntity<String> entity = restTemplate.getForEntity(requestUrl, String.class);
            logger.info("loginUrlEntity:" + entity.toString());
            String body = entity.getBody();
            JSONObject result = JSONObject.parseObject(body);
            if (result == null || !result.containsKey("openid")) {
                throw new BusinessException("登录出错，请稍后重试～");
            }
            sessionKey = result.getString("session_key");
            openId = result.getString("openid");
        }

        BuyerUser user = this.getBaseMapper().selectOne(
                new LambdaQueryWrapper<BuyerUser>()
                        .eq(BuyerUser::getDeleted, 0)
                        .eq(BuyerUser::getOpenId, openId)
        );
        if (user == null) {
            // 不存在，需新增
            user = new BuyerUser();
            String id = IDGenerator.generate16("WxUser");
            user.setId(id);
            user.setUnionId("");
            user.setOpenId(openId);
            user.setCompanyId(baicInterfaceConfig.getCompanyId());
            user.setDeleted(0);
            user.setCreatedBy(id);
            user.setCreateTime(LocalDateTime.now());
            user.setUpdatedBy(id);
            user.setUpdatedTime(LocalDateTime.now());
            this.getBaseMapper().insert(user);
            // Token塞入所需信息
            User webUser = new User();
            webUser.setId(id);
            webUser.setCompanyId(baicInterfaceConfig.getCompanyId());
            webUser.setSysType("Wx");
            // 创建jwt
            String token = jwtUtil.createToken(webUser);
            logger.info("小程序用户登录token:" + token);
            return new WxLoginOutVo(sessionKey, openId, token, true);
        } else {
            if (StringUtils.isEmpty(user.getPhone())) {
                User webUser = new User();
                webUser.setId(user.getId());
                webUser.setCompanyId(user.getCompanyId());
                webUser.setSysType("Wx");
                String token = jwtUtil.createToken(webUser);
                logger.info("小程序用户登录token:" + token);
                return new WxLoginOutVo(sessionKey, openId, token, true);
            } else {
                // 静默登录
                User webUser = new User();
                webUser.setId(user.getId());
                webUser.setCompanyId(user.getCompanyId());
                webUser.setSysType("Wx");
                String token = jwtUtil.createToken(webUser);
                logger.info("小程序用户登录token:" + token);
                return new WxLoginOutVo(sessionKey, openId, token, false);
            }
        }
    }

    @Override
    public void getPhoneNum(GetPhoneNumInVo inVo) {
        String access_token;
        String openId = inVo.getOpenId();
        String phoneNum;

        LambdaQueryWrapper<BaicInterfaceConfig> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BaicInterfaceConfig::getCompanyId, TokenService.getUserBytoken().getCompanyId());
        BaicInterfaceConfig baicInterfaceConfig = iBaicInterfaceConfigService.getBaseMapper().selectOne(queryWrapper);
        if (baicInterfaceConfig == null) {
            throw new BusinessException("登录出错，请稍后重试～");
        }
        String appId = baicInterfaceConfig.getAppId();
        String appSecret = baicInterfaceConfig.getAppSecret();
        // 获取全局调用凭证
        access_token = AccessTokenUtil.getAccessToken(appId, appSecret);

        String getPhoneNumberRequestUrl = String.format(getPhoneNumberUrl, access_token);
        //参数
        Map<String, Object> query = new HashMap<>();
        query.put("code", inVo.getCode());
        RestTemplate restTemplate1 = new RestTemplate();
        ResponseEntity<String> entity = restTemplate1.postForEntity(getPhoneNumberRequestUrl, query, String.class);
        logger.info("getPhoneNumberRequestUrlEntity:" + entity.toString());
        String body = entity.getBody();
        JSONObject result = JSONObject.parseObject(body);
        if (result == null || !result.containsKey("phone_info")) {
            throw new BusinessException("调用获取手机号接口出错，请稍后重试～");
        }
        JSONObject phone_info = result.getJSONObject("phone_info");
        phoneNum = phone_info.getString("phoneNumber");

        // 更新手机号
        LambdaQueryWrapper wrapper = new LambdaQueryWrapper<BuyerUser>()
                .eq(BuyerUser::getDeleted, 0)
                .eq(BuyerUser::getOpenId, openId);
        BuyerUser user = this.getBaseMapper().selectOne(wrapper);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        user.setPhone(phoneNum);
        this.getBaseMapper().update(user, wrapper);
    }

    @Override
    public void setUserInfo(UserInfoInVo inVo) {
        // 更新昵称，头像
        LambdaQueryWrapper wrapper = new LambdaQueryWrapper<BuyerUser>()
                .eq(BuyerUser::getOpenId, inVo.getOpenId());
        BuyerUser user = this.getBaseMapper().selectOne(wrapper);
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        if (org.springframework.util.StringUtils.hasLength(inVo.getAvatarUrl())) {
            user.setAvatarUrl(inVo.getAvatarUrl());
        }
        if (org.springframework.util.StringUtils.hasLength(inVo.getNickName())) {
            user.setNickName(inVo.getNickName());
        }
        this.getBaseMapper().update(user, wrapper);
    }

    @Override
    public String getUserPhoneNum() {
        // 获取手机号
        BuyerUser user = this.getBaseMapper().selectById(TokenService.getUserBytoken().getId());
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        if (StringUtils.isNotEmpty(user.getPhone())) {
            return user.getPhone();
        }
        return null;
    }

    @Override
    public PageResult<BuyerUserOutVo> getBuyerUserList(UserQueryInVo inVo, Long pageNo, Long pageSize) {
        // 分页查询
        Page<BuyerUser> page = new Page<>(pageNo, pageSize);
        LambdaQueryWrapper<BuyerUser> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BuyerUser::getCompanyId, TokenService.getUserBytoken().getCompanyId());
        queryWrapper.like(StringUtils.isNotEmpty(inVo.getPhone()), BuyerUser::getPhone, inVo.getPhone());
        queryWrapper.like(StringUtils.isNotEmpty(inVo.getNickName()), BuyerUser::getNickName, inVo.getNickName());
        queryWrapper.like(StringUtils.isNotEmpty(inVo.getName()), BuyerUser::getRealName, inVo.getName());
        queryWrapper.eq(!(inVo.getIsFk() == null), BuyerUser::getIsFk, inVo.getIsFk());
        queryWrapper.eq(!(inVo.getIsEnable() == null), BuyerUser::getIsEnable, inVo.getIsEnable());

        queryWrapper.ge(inVo.getStartTime_fk() != null, BuyerUser::getFkTime, inVo.getStartTime_fk());
        if (inVo.getEndTime_fk() != null) {
            queryWrapper.le(BuyerUser::getFkTime, LocalDateTime.of(inVo.getEndTime_fk(), LocalTime.MAX));
        }

        queryWrapper.ge(inVo.getStartTime_enable() != null, BuyerUser::getEnableTime, inVo.getStartTime_enable());
        if (inVo.getEndTime_enable() != null) {
            queryWrapper.le(BuyerUser::getEnableTime, LocalDateTime.of(inVo.getEndTime_enable(), LocalTime.MAX));
        }

        // 查询 buyerUsers 列表
        IPage<BuyerUser> iPage = this.baseMapper.selectPage(page, queryWrapper);

        // 将 buyerUsers 列表转换为 BuyerUserOutVo 对象列表
        List<BuyerUserOutVo> buyerUserOutVos = BeanUtil.copyToList(iPage.getRecords(), BuyerUserOutVo.class);

        // 封装成 PageResult 对象并返回
        return new PageResult<>(iPage.getTotal(), iPage.getCurrent(), iPage.getSize(), iPage.getPages(), buyerUserOutVos);
    }

    @Override
    public BuyerUserOutVo getBuyerUser(String id) {
        BuyerUser buyerUser = this.baseMapper.selectById(id);
        return BeanUtil.toBean(buyerUser, BuyerUserOutVo.class);
    }

    @Override
    public void updateStatus(UserUpdateInVo inVo) {
        BuyerUser user = this.getBaseMapper().selectById(inVo.getId());
        if (user == null) {
            throw new BusinessException("用户不存在");
        }
        // 风控
        if (inVo.getIsFk() != null) {
            user.setIsFk(inVo.getIsFk());
            user.setFkTime(LocalDateTime.now());
        }
        // 黑/白名单
        if (inVo.getIsEnable() != null) {
            user.setIsEnable(inVo.getIsEnable());
            user.setEnableTime(LocalDateTime.now());
        }

        this.getBaseMapper().updateById(user);
    }

    @Override
    public void delete(UserDeleteInVo inVo) {
        // 批量删除
        inVo.getIds().forEach(a -> {
            this.baseMapper.deleteById(a);
        });
    }


}
